package com.rtx.job.handler;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rtx.api.annotation.DataSourceAnnotation;
import com.rtx.job.bean.po.EdiSql;
import com.rtx.job.service.EdiJobService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class EdiJobHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private EdiJobService ediJobService;

    /**
     * 获取数据
     * @param whseid 仓库
     * @param ediSqlList 查询sql
     * @return 数据
     */
    @DataSourceAnnotation
    public List<Map<String, Object>> selectData(String whseid,List<EdiSql> ediSqlList){
        //获取主sql
        EdiSql sql = ediSqlList.stream().filter(s -> "1".equals(s.getType()) && s.getId() == s.getParentId()).findAny().orElse(null);
        //获取主sql数据
        List<Map<String, Object>> list = ediJobService.executeQueryListSql(sql.getSql());
        //获取子节点数据
        for(Map<String, Object> m : list){
            selectSubData(sql,ediSqlList,m);
        }
        return list;
    }

    /**
     * 获取子节点数据
     * @param sql 父节点SQL
     * @param ediSqlList 查询SQL
     * @param map 父节点数据
     */
    private void selectSubData(EdiSql sql,List<EdiSql> ediSqlList,Map<String, Object> map){
        //获取子sql
        List<EdiSql> subList = ediSqlList.stream().filter(s -> "1".equals(s.getType()) && s.getId() != s.getParentId() && s.getParentId() == sql.getId()).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(subList)){
            return;
        }
        for(EdiSql sub : subList){
            String subsql = replaceSqlCondition(sub,map);
            List<Map<String, Object>> sub_list = ediJobService.executeQueryListSql(subsql);
            map.put(sub.getNodeName(),sub_list);
            for(Map<String, Object> m : sub_list){
                selectSubData(sub,ediSqlList,m);
            }
        }
    }

    /**
     * 替换sql条件
     * @param sql sql配置
     * @param m 父节点数据
     * @return 执行sql
     */
    private String replaceSqlCondition(EdiSql sql,Map<String, Object> m){
        //预处理sql
        String preSql = sql.getSql();
        //条件
        String condition = sql.getCondition();
        if(StringUtils.hasText(condition)){
            //解析条件  {"orderkey":"orderkey1","sku":"sku"}
            JSONObject j = JSON.parseObject(condition);
            for(Map.Entry<String, Object> entry : j.entrySet()){
                preSql = preSql.replace("#" + entry.getKey() + "#",String.valueOf(m.get(entry.getValue())));
            }
        }
        return preSql;
    }

    /**
     * 替换sql条件
     * @param sql sql配置
     * @param m 父节点数据
     * @return 执行sql
     */
    private String replaceSqlCondition(String sql,Map<String, Object> m){
        //预处理sql
        String preSql = sql;
        for(Map.Entry entry : m.entrySet()){
            preSql = preSql.replace("#" + entry.getKey() + "#",String.valueOf(m.get(entry.getValue())));
        }
        return preSql;
    }

    /**
     * 解析结果
     * @param data 请求数据
     * @param template 模板
     * @param result 结果
     * @return 结果
     */
    public Map<String,Object> analysisResults(Map<String,Object> data,String template,String result){
        Map<String,Object> map = new HashMap<>();
        try {
            //String template = "{\"source\":{\"orderkey\":\"orderkey\",\"type\":\"type\"},\"result\":{\"code\":\"\",\"msg\":\"\",\"target\":\"S\"}}";
            //解析模板
            cn.hutool.json.JSONObject templateJson = JSONUtil.parseObj(template);
            cn.hutool.json.JSONObject t_source = templateJson.getJSONObject("source");
            cn.hutool.json.JSONObject t_result = templateJson.getJSONObject("result");
            //源数据条件
            for(String key : t_source.keySet()){
                map.put(key,data.get(t_source.getStr(key)));
            }
            if(StringUtils.hasText(result)){
                //转化结果JSON
                cn.hutool.json.JSON resultJson = JSONUtil.parse(result);
                //结果条件
                if(t_result == null){
                    map.put("code","S");
                }else{
                    //返回结果成功的目标值
                    String target = t_result.getStr("target");
                    if(StringUtils.hasText(target)){
                        //获取结果的返回值，如果跟目标值相等，则为S
                        String rel = resultJson.getByPath(t_result.getStr("code"),String.class);
                        map.put("code",target.equals(rel) ? "S" : "E");
                    }else{
                        map.put("code","S");
                    }
                    //返回结果的其他条件
                    for(String key : t_result.keySet()){
                        if("code".equals(key) || "target".equals(key)){
                           continue;
                        }
                        map.put(key,resultJson.getByPath(t_result.getStr(key)));
                    }
                }
            }else{
                map.put("code","E");
                map.put("msg","目标接口无结果返回");
            }
        } catch (Exception e) {
            logger.error("解析结果异常",e);
            map.put("code","E");
            map.put("msg",e.getMessage());
        }
        return map;
    }

    /**
     * 更新结果
     * @param whseid 仓库
     * @param map 结果
     * @param ediSqlList 更新sql
     */
    @DataSourceAnnotation
    public void updateResult(String whseid,Map<String,Object> map,List<EdiSql> ediSqlList){
        //获取更新sql  update api_orders set editflag='#code#',rtxqueue=rtxqueue+1 where batchid='#batchid#' and externorderkey='#externorderkey#'
        List<EdiSql> sqlList = ediSqlList.stream().filter(s -> "2".equals(s.getType())).collect(Collectors.toList());
        for(EdiSql sql : sqlList){
            String preSql = sql.getSql();
            for(Map.Entry entry : map.entrySet()){
                preSql = preSql.replace("#" + entry.getKey() + "#",String.valueOf(entry.getValue()));
            }
            ediJobService.executeSql(preSql);
        }
    }
}
